import { defineStore, storeToRefs } from 'pinia'
import { useSlidesStore } from '@/store'
import message from '@/utils/message'
import useExport from '@/hooks/useExport'
import useProposalOrTemplate from '@/hooks/useProposalOrTemplate'
import useImport from '@/hooks/useImport'

export type ProposalQuoteDetail = {
  customerName: string
  projectAddress: string
  superintendent: string
  deptName: string
  deptAddress: string
  phoneNumber: string
  userNickName: string
  funcPrice: number
  eqptPrice: number
  travelPrice: number
  projectName: string
  funcPriceStr: string
  eqptPriceStr: string
  travelPriceStr: string
  totalPriceStr: string
  taxes1Str: string
  taxes2St1: string
  allTotalStr: string
}

export type ProposalForm = {
  name: string
  proposalCompanyName: string
  proposalDeptName: string
  saleName: string
  proposalTime: string
  proposalName: string
  createBy: string
  companyName: string
  companyContacts: string
  companyEmail: string
  projectName: string
  projectDesc: string
  projectImg: string
  descType: number
  worthDescType: number
  contentDescType: number

  quoteId: number
  quoteName: string
}

export interface ProposalState {
  /** 操作类型 */
  type: 'look' | 'edit' | 'copy' | 'add' | 'module-add' | ''
  /** i18n */
  language: 'cn' | 'en' | 'jp'
  /** 权限
   * 1：只读
   * 2：编辑
   * 3：结束邀请
   */
  projectPermission: 1 | 2 | 3
  /** 表单数据 */
  form?: ProposalForm

  quoteDetail?: ProposalQuoteDetail

  /** 第几页插入 */
  insetPage: number

  /** 是否关闭 */
  isClose?: number
  /** 是否删除 */
  isDelete?: number
  /** 是否默认布局 */
  isDefault?: 0 | 1
  /** 最后一个默认布局的名称 */
  lastDefaultLayoutName?: string
  /** 项目类型 */
  itemType?: string

  /** 模板ID */
  moudleId?: string
  /** 提案数据ID */
  proposalId?: number
  layoutId?: string
  /**
   * 1-子系统
   * 2-设备
   * 3-评分
   * 4-节能价值
   * 5-报价单
   */
  layoutType?: 1 | 2 | 3 | 4 | 5
  /**
   * 1-系统提案
   * 2-评分提案
   */
  proposalLayoutType?: 1 | 2

  /**
   * 1-系统提案
   * 2-评分提案
   */
  moudleType?: 1 | 2
  /**
   * 1-系统提案
   * 2-评分提案
   */
  proposalType?: 1 | 2

  /** ppt地址 */
  pptUrl?: string
  /** 项目ID */
  projectId?: number
  /** 模板数据 */
  pptTemplateData?: { [key: string]: any }
  /** 设备布局 */
  eqptTemplate?: { [key: string]: any }
  /** 设备数据 */
  equipmentList?: any[]
  /** 软件布局排版 */
  softwareTemplate?: { [key: string]: any }
  /** 软件布局 */
  softwareList?: any[]
  /** 评分布局排版 */
  scoreTemplate?: { [key: string]: any }
  /** 评分数据 */
  scoreData?: { [key: string]: any }

  downloadUrl?: string
  /** 提案封面图片 */
  coverImage?: string
}
export const useProposalStore = defineStore('proposal', {
  state: (): ProposalState => ({
    type: '',
    pptUrl: '',
    pptTemplateData: {},
    isClose: 0,
    isDelete: 0,
    isDefault: 0,
    insetPage: 0,
    projectId: undefined,
    moudleId: undefined,
    layoutId: undefined,
    layoutType: undefined,
    language: 'cn',
    projectPermission: 1,
  }),
  actions: {
    setProposalData(data: ProposalState) {
      Object.assign(this, data)
    },
    async setCoverImage(imageFile: File) {
      const { uploadQiniu } = useProposalOrTemplate()
      const { code, msg, url } = await uploadQiniu(imageFile)
      if (code !== 200) throw new Error(msg)
      this.coverImage = url
    },

    /* 保存提案数据 - 新增、复制 */
    async saveProposalData() {
      try {
        const { slides } = storeToRefs(useSlidesStore())
        const { exportPPTX, exportSpecificFile } = useExport()
        const { uploadProposalDataFile, addProposalData } =
          useProposalOrTemplate()

        // 导出处理后的提案数据为file，分别存pptx文件和pptlist文件
        const result_file = (await exportPPTX(slides.value, false, false, {
          file: true,
        })) as File
        // 将导出的 url 存到后端
        const { msg, code, url } = (await uploadProposalDataFile(
          this.projectId,
          result_file,
        )) as any
        if (code !== 200) return message.error(msg)

        const result_listFile = (await exportSpecificFile(slides.value, {
          file: true,
        })) as File
        const {
          msg: list_msg,
          code: list_code,
          url: list_url,
        } = (await uploadProposalDataFile(
          this.projectId,
          result_listFile,
        )) as any
        if (list_code !== 200) return message.error(list_msg)

        if (!this.projectId) return message.error('缺少项目ID')

        // 添加数据
        const result = await addProposalData({
          // 用于接口传参,包含提案名称，项目名称等
          ...this.form,
          proposalImg: this.coverImage,
          // pptlist 文件
          proposalFileUrl: list_url,
          // ppt 文件
          downloadUrl: url,
          projectId: this.projectId,
          // 模板 id，用于回显
          moudleId: this.pptTemplateData?.moudleId || null,
          // 软件排板布局 id，用于回显
          proposalSystemLayout: this.softwareTemplate?.layoutId || 0,
          // 设备排板布局 id
          proposalEqptLayout: this.eqptTemplate?.layoutId || 0,
          isClose: this.isClose,
        })

        if (result.code !== 200) return message.error(result.msg)
        return message.success('保存成功')
      }
      catch (err) {
        throw new Error(typeof err === 'string' ? err : JSON.stringify(err))
      }
    },
    /* 更新提案数据 - 编辑 */
    async updateProposalData() {
      try {
        const { slides, title } = storeToRefs(useSlidesStore())
        const { exportPPTX, exportSpecificFile } = useExport()
        const { updateProposalDataFile, editProposalData } =
          useProposalOrTemplate()
        // 导出处理后的提案数据为file，分别存pptx文件和pptlist文件
        const pptx = (await exportPPTX(slides.value, false, false, {
          file: true,
        })) as File
        const pptist = (await exportSpecificFile(slides.value, {
          file: true,
        })) as File
        // 将导出的 url 存到后端
        if (!this.proposalId) return message.error('缺少提案ID')

        const { msg, code, url } = await updateProposalDataFile(
          this.proposalId,
          pptist,
          pptx,
        )
        if (code !== 200) return message.error(msg)

        if (!this.proposalId) return message.error('缺少提案ID')

        const result = await editProposalData({
          proposalId: this.proposalId,
          proposalImg: this.coverImage,
          proposalName: title.value,
        })
        if (result.code !== 200) return message.error(result.msg)
        return message.success('保存成功')
      }
      catch (err) {
        throw new Error(err + '')
      }
    },
    /* 闭合提案数据 */
    async closeProposalData() {
      try {
        const { closeProposalData } = useProposalOrTemplate()
        const result = (await closeProposalData(this.proposalId)) as any
        if (result.code !== 200) return message.error(result.msg)
        return message.success('操作成功')
      }
      catch (err) {
        message.error('操作失败')
        throw new Error(err + '')
      }
    },
    /* 新增提案模板，模板名会按照文件名 */
    async addTemplateData() {
      try {
        const { slides } = storeToRefs(useSlidesStore())
        const { exportSpecificFile } = useExport()
        const { uploadProposalModuleFile } = useProposalOrTemplate()

        // 导出处理后的提案数据为file
        const result_file = (await exportSpecificFile(slides.value, {
          file: true,
        })) as File
        if (!this.moudleType) return message.error('缺少模板类型')

        // 上传提案模板文件
        const result = await uploadProposalModuleFile(
          result_file,
          this.moudleType,
          this.itemType!,
          this.coverImage,
        )

        if (result.code !== 200) return message.error(result.msg)
        return message.success('保存成功')
      }
      catch (err) {
        throw new Error(err + '')
      }
    },
    /* 更新提案模板 */
    async updateTemplateData() {
      try {
        const { slides, title } = storeToRefs(useSlidesStore())

        const { exportSpecificFile } = useExport()
        const { updateProposalModuleFile, editProposalModule } =
          useProposalOrTemplate()

        // 导出处理后的提案数据为file
        const result_file = (await exportSpecificFile(slides.value, {
          file: true,
        })) as File

        // 更新提案模板文件
        const result = (await updateProposalModuleFile(
          this.moudleId,
          this.itemType!,
          result_file,
        )) as any
        if (result.code !== 200) return message.error(result.msg)

        if (!this.moudleId) return message.error('缺少模板ID')
        const result_data = await editProposalModule({
          moudleId: this.moudleId,
          moudleImg: this.coverImage,
          moudleName: title.value,
        })
        if (result_data.code !== 200) return message.error(result_data.msg)
        return message.success('保存成功')
      }
      catch (err) {
        throw new Error(err + '')
      }
    },
    /*  新增排板布局,布局类型 1-子系统 2-设备 3-评分 4-节能价值 5-报价单*/
    async addLayoutFile() {
      try {
        const { slides } = useSlidesStore()
        const { exportSpecificFile } = useExport()
        const { uploadLayoutFile } = useProposalOrTemplate()

        // const result_file = (await exportPPTX(slides, false, false, { file: true })) as File
        const result_file = (await exportSpecificFile(slides, {
          file: true,
        })) as File

        if (!this.layoutType) return message.error('缺少布局类型')
        if (!this.proposalLayoutType) return message.error('缺少提案布局类型')
        const result = (await uploadLayoutFile(
          this.layoutType,
          this.proposalLayoutType,
          result_file,
          this.itemType!,
          this.coverImage,
        )) as any
        if (result.code !== 200) return message.error(result.msg)
        return message.success('保存成功')
      }
      catch (err) {
        throw new Error(err + '')
      }
    },
    /* 更新排板类型 */
    async updateLayoutFile() {
      try {
        const { slides, title } = storeToRefs(useSlidesStore())

        const { exportSpecificFile } = useExport()
        const { editLayoutFile } = useProposalOrTemplate()

        // const result_file = (await exportPPTX(slides.value, false, false, { file: true })) as File
        const result_file = (await exportSpecificFile(slides.value, {
          file: true,
        })) as File

        if (!this.proposalLayoutType) return message.error('缺少提案布局类型')

        const result = (await editLayoutFile({
          layoutId: this.layoutId,
          layoutName: title.value,
          proposalLayoutType: this.proposalLayoutType,
          file: result_file,
          layoutImg: this.coverImage,
          itemType: this.itemType!,
        })) as any
        if (result.code !== 200) return message.error(result.msg)
        return message.success('保存成功')
      }
      catch (err) {
        throw new Error(err + '')
      }
    },

    /* 解析 pptx 文件 url 为 json 数据 */
    async parsePPTXForJson(url: string): Promise<any[] | object> {
      try {
        const { urlToFileList } = useProposalOrTemplate()
        const { importPPTXJSON } = useImport()

        const fileList = await urlToFileList(url)
        const jsonPPTX = await importPPTXJSON(fileList)
        return JSON.parse(jsonPPTX || '{}')
      }
      catch (err) {
        console.log(err, url)
        message.error('文件解析json失败，请检查url是否可用：' + url)
        throw new Error(err + '')
      }
    },
    /* 解析 pptist 文件 url 为 json 数据 */
    async parsePPTistForJson(url: string): Promise<any[] | object> {
      try {
        const { urlToFileList } = useProposalOrTemplate()
        const { importSpecificJSON } = useImport()
        const fileList = await urlToFileList(url)
        const jsonPPTist = await importSpecificJSON(fileList)
        return JSON.parse(jsonPPTist || '{}')
      }
      catch (err) {
        console.log(err, url)
        message.error('文件解析json失败，请检查url是否可用：' + url)
        throw new Error(err + '')
      }
    },

    /* 解析 pptx 文件 url 导入页面 */
    async parsePPTXForInsetPage(url: string): Promise<void> {
      try {
        const { urlToFileList } = useProposalOrTemplate()
        const { importPPTXFile, importSpecificFile } = useImport()

        // 判断url后缀是pptx还是pptlist文件
        const fileList = await urlToFileList(url)
        if (url.includes('.pptx')) {
          await importPPTXFile(fileList)
        }
        else if (url.includes('.pptlist')) {
          await importSpecificFile(fileList)
        }
      }
      catch (err) {
        console.log(err, url)
        message.error('文件导入失败，请检查url是否可用:' + url)
        throw new Error(err + '')
      }
    },
    /* 解析 pptist 文件 url 导入页面 */
    async parsePPTistForInsetPage(url: string): Promise<void> {
      try {
        const { urlToFileList } = useProposalOrTemplate()
        const { importSpecificFile } = useImport()

        const fileList = await urlToFileList(url)
        importSpecificFile(fileList)
      }
      catch (err) {
        console.log(err)
        message.error('文件导入失败，请检查url是否可用')
        throw new Error(err + '')
      }
    },
  },
  getters: {
    // 提案数据编辑
    isProposalEdit(state): boolean {
      return state.type === 'edit' && !!state.projectId
    },
    // 提案数据新增
    isProposalCreate(state): boolean {
      return (
        (state.type === 'add' || state.type === 'copy') && !!state.projectId
      )
    },
    // 提案模板新增
    isModuleCreate(state): boolean {
      return state.type === 'module-add'
    },
    // 提案模板编辑
    isModuleEdit(state): boolean {
      return state.type === 'edit' && !!state.moudleId
    },
    // 排板布局查看
    isProposalLayoutView(state): boolean {
      return (
        state.type === 'look' &&
        !!state.layoutType &&
        !!state.proposalLayoutType
      )
    },
    // 排板布局新增
    isProposalLayoutCreate(state): boolean {
      return (
        state.type === 'add' && !!state.layoutType && !!state.proposalLayoutType
      )
    },
    // 排板布局编辑
    isProposalLayoutEdit(state): boolean {
      return state.type === 'edit' && !!state.layoutId && !!state.layoutType
    },
  },
})
